import sounddevice as sd
import soundfile as sf
import threading
import os
import warnings


class AlertSystem:
    def __init__(self, audio_file=r"C:\Users\27571\Desktop\机器视觉\aisaka-taiga\opencv\项目\xm3677.wav"):
        self.audio_file = audio_file
        self.is_playing = False

        print(f"音频文件路径: {self.audio_file}")


        if not os.path.exists(self.audio_file):
            warnings.warn(f"音频文件不存在: {self.audio_file}")
            print("将使用系统蜂鸣声作为备用警报")

        try:
            devices = sd.query_devices()
            print("可用音频设备:", devices)
        except Exception as e:
            print(f"查询音频设备时出错: {e}")

    def play_alert(self):
        if not self.is_playing:
            self.is_playing = True
            try:
                if not os.path.exists(self.audio_file):
                    raise FileNotFoundError(f"音频文件不存在: {self.audio_file}")

                try:
                    data, fs = sf.read(self.audio_file, dtype='float32')
                except Exception as e:
                    print(f"读取音频文件失败: {e}")
                    # 尝试使用系统蜂鸣声作为备用
                    self.play_fallback_alert()
                    return


                if len(data) == 0:
                    raise ValueError("音频文件为空或无效")

                print(f"播放音频: {self.audio_file}, 采样率: {fs} Hz")
                sd.play(data, fs)
                sd.wait()

            except Exception as e:
                print(f"播放音频时出错: {e}")
                self.play_fallback_alert()
            finally:
                self.is_playing = False

    def play_fallback_alert(self):
        try:
            import winsound
            print("使用系统蜂鸣声作为警报")
            winsound.Beep(1000, 2000)
        except ImportError:
            print("使用终端蜂鸣声作为警报")
            print("\a")
            import time
            time.sleep(0.5)
            print("\a")

    def play_alert_async(self):
        thread = threading.Thread(target=self.play_alert)
        thread.daemon = True
        thread.start()

    def stop_alert(self):
        sd.stop()
        self.is_playing = False